package com.nanyang.tms.service.product.impl;

import com.nanyang.common.core.annotation.SystemLog;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.domain.ApiResult;
import com.nanyang.common.core.exception.ExceptionProcessorUtils;
import com.nanyang.common.core.page.PageBean;
import com.nanyang.common.core.page.PageTableBean;
import com.nanyang.common.tool.utils.convert.BeanUtils;
import com.nanyang.tms.api.dto.request.product.ProductQueryRequest;
import com.nanyang.tms.api.dto.request.product.ProductUpdateStateRequest;
import com.nanyang.tms.api.dto.request.product.add.ProductBaseAddRequest;
import com.nanyang.tms.api.dto.request.product.add.ProductWeightModelAddRequest;
import com.nanyang.tms.api.dto.request.product.update.ProductBaseUpdateRequest;
import com.nanyang.tms.api.dto.request.product.update.ProductWeightModelUpdateRequest;
import com.nanyang.tms.api.dto.response.product.*;
import com.nanyang.tms.api.service.product.ProductRpcService;
import com.nanyang.tms.dao.product.ProductInfoDao;
import com.nanyang.tms.domain.product.*;
import com.nanyang.tms.manager.product.ProductManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service(version = "1.0.0", timeout = 10000, retries = 0, validation = "true")
public class ProductRpcServiceImpl implements ProductRpcService {
    @Autowired
    private ProductManager productManager;
    @Autowired
    private ProductInfoDao productDao;
    @Override
    public ApiResult<PageBean<ProductPageResponse>> listProduct(ProductQueryRequest param) {
        ApiResult<PageBean<ProductPageResponse>> apiResult = new ApiResult<>();
        try {
            param.requestCheck();
            ProductQuery query = new ProductQuery();
            BeanUtils.copyProperties(param, query);
            PageBean<ProductInfoVO> productList = productManager.listProduct(query);
            PageBean<ProductPageResponse> resultList = new PageTableBean<>(query.getPageIndex(), query.getPageSize());
            resultList.setTotalItem(productList.getTotalItem());
            BeanUtils.copyListProperties(productList.getData(), resultList.getData(), ProductPageResponse.class);
            apiResult.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            apiResult.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            apiResult.setData(resultList);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(apiResult, e);
        }
        return apiResult;
    }
    @Override
    public ApiResult<PageBean<ProductPageKeyResponse>> listProductByKey(ProductQueryRequest param) {
        ApiResult<PageBean<ProductPageKeyResponse>> apiResult = new ApiResult<>();
        try {
            param.requestCheck();
            param.setState(0);
            ProductQuery query = new ProductQuery();
            BeanUtils.copyProperties(param, query);
            PageBean<ProductInfoVO> productList = productManager.listProduct(query);
            PageBean<ProductPageKeyResponse> resultList = new PageTableBean<>(query.getPageIndex(), query.getPageSize());
            resultList.setTotalItem(productList.getTotalItem());
            BeanUtils.copyListProperties(productList.getData(), resultList.getData(), ProductPageKeyResponse.class);
            apiResult.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            apiResult.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            apiResult.setData(resultList);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(apiResult, e);
        }
        return apiResult;
    }
    @Override
    public ApiResult<ProductBaseResponse> selectByCode(String code) {
        ApiResult<ProductBaseResponse> result = new ApiResult<>();
        try {
            ProductBaseResponse productBaseResponse = new ProductBaseResponse();
            ProductBaseVO productBaseVO = productManager.selectProductByCode(code);

            ProductInfoResponse productInfoResponse=new ProductInfoResponse();
            BeanUtils.copyProperties(productBaseVO.getProductInfoVO(),productInfoResponse);
            productBaseResponse.setProductInfoResponse(productInfoResponse);

            ProductRuleResponse productRuleResponse=new ProductRuleResponse();
            BeanUtils.copyProperties(productBaseVO.getProductRuleVO(),productRuleResponse);
            productBaseResponse.setProductRuleResponse(productRuleResponse);

            List<ProductCarryRuleResponse> productCarryRuleResponseList=new ArrayList<>();
            BeanUtils.copyListProperties(productBaseVO.getProductCarryRuleVOList(),productCarryRuleResponseList,ProductCarryRuleResponse.class);
            productBaseResponse.setProductCarryRuleResponseList(productCarryRuleResponseList);

            List<ProductPartResponse> productPartResponseList=new ArrayList<>();
            BeanUtils.copyListProperties(productBaseVO.getProductPartVOList(),productPartResponseList,ProductPartResponse.class);
            productBaseResponse.setProductPartResponseList(productPartResponseList);

            ProductWeightModelResponse productWeightModelResponse=new ProductWeightModelResponse();
            ProductWeightModelVO productWeightModelVO = productBaseVO.getProductWeightModelVO();
            BeanUtils.copyProperties(productWeightModelVO,productWeightModelResponse);
            List<ProductWeightRuleResponse> productWeightRuleResponseList=new ArrayList<>();
            BeanUtils.copyListProperties(productWeightModelVO.getProductWeightRuleVOList(),productWeightRuleResponseList,ProductWeightRuleResponse.class);
            productWeightRuleResponseList.forEach(productWeightRuleResponse->{
                if(StringUtils.isNotEmpty(productWeightRuleResponse.getCityCode())&&"ALL".equals(productWeightRuleResponse.getCityCode())){
                    productWeightRuleResponse.setCityCode("");
                    productWeightRuleResponse.setCityName("");
                }
                if(StringUtils.isNotEmpty(productWeightRuleResponse.getCountyCode())&&"ALL".equals(productWeightRuleResponse.getCountyCode())){
                    productWeightRuleResponse.setCountyCode("");
                    productWeightRuleResponse.setCountyName("");
                }
            });
            productWeightModelResponse.setProductWeightRuleResponseList(productWeightRuleResponseList);
            productBaseResponse.setProductWeightModelResponse(productWeightModelResponse);

            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(productBaseResponse);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }

    @Override
    public ApiResult<Boolean> saveProduct(ProductBaseAddRequest param) {
        ApiResult<Boolean> result = new ApiResult<Boolean>();
        try {
            param.requestCheck();
            ProductBaseDO productBaseDO = new  ProductBaseDO();
            productBaseDO.setGmtCreatePin(param.getPin());
            productBaseDO.setIp(param.getIp());

            ProductInfoDO productInfoDO=new ProductInfoDO();
            BeanUtils.copyProperties(param.getProductAddRequest(),productInfoDO);
            productBaseDO.setProductInfoDO(productInfoDO);

            ProductRuleDO productRuleDO=new ProductRuleDO();
            BeanUtils.copyProperties(param.getPruductRuleAddRequest(),productRuleDO);
            productBaseDO.setProductRuleDO(productRuleDO);

            List<ProductCarryRuleDO> productCarryRuleDOList=new ArrayList<>();
            BeanUtils.copyListProperties(param.getProductCarryRuleAddRequestList(),productCarryRuleDOList,ProductCarryRuleDO.class);
            productBaseDO.setProductCarryRuleDOList(productCarryRuleDOList);

            ProductWeightModelDO productWeightModelDO=new ProductWeightModelDO();
            ProductWeightModelAddRequest productWeightModelAddRequest = param.getProductWeightModelAddRequest();
            BeanUtils.copyProperties(productWeightModelAddRequest,productWeightModelDO);
            List<ProductWeightRuleDO> productWeightRuleDOList=new ArrayList<>();
            BeanUtils.copyListProperties(productWeightModelAddRequest.getProductWeightRuleAddRequestList(),productWeightRuleDOList,ProductWeightRuleDO.class);
            productWeightModelDO.setProductWeightRuleDOList(productWeightRuleDOList);

            productBaseDO.setProductWeightModelDO(productWeightModelDO);

            List<ProductPartDO> productPartDOList=new ArrayList<>();
            BeanUtils.copyListProperties(param.getProductPartAddRequestList(),productPartDOList,ProductPartDO.class);
            productBaseDO.setProductPartDOList(productPartDOList);

            productManager.saveProduct(productBaseDO);

            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }

    @Override
    public ApiResult<Boolean> updateProduct(ProductBaseUpdateRequest param) {
        ApiResult<Boolean> result = new ApiResult<Boolean>();
        try {
            param.requestCheck();
            ProductBaseDO productBaseDO = new  ProductBaseDO();
            productBaseDO.setGmtModifiedPin(param.getPin());
            productBaseDO.setIp(param.getIp());

            ProductInfoDO productInfoDO=new ProductInfoDO();
            BeanUtils.copyProperties(param.getProductUpdateRequest(),productInfoDO);
            productBaseDO.setProductInfoDO(productInfoDO);

            ProductRuleDO productRuleDO=new ProductRuleDO();
            BeanUtils.copyProperties(param.getPruductRuleUpdateRequest(),productRuleDO);
            productBaseDO.setProductRuleDO(productRuleDO);

            List<ProductCarryRuleDO> productCarryRuleDOList=new ArrayList<>();
            BeanUtils.copyListProperties(param.getProductCarryRuleUpdateRequestList(),productCarryRuleDOList,ProductCarryRuleDO.class);
            productBaseDO.setProductCarryRuleDOList(productCarryRuleDOList);

            ProductWeightModelUpdateRequest productWeightModelUpdateRequest = param.getProductWeightModelUpdateRequest();
            ProductWeightModelDO productWeightModelDO=new ProductWeightModelDO();
            BeanUtils.copyProperties(productWeightModelUpdateRequest,productWeightModelDO);
            List<ProductWeightRuleDO> productWeightRuleDOList=new ArrayList<>();
            BeanUtils.copyListProperties(productWeightModelUpdateRequest.getProductWeightRuleUpdateRequestList(),productWeightRuleDOList,ProductWeightRuleDO.class);
            productWeightModelDO.setProductWeightRuleDOList(productWeightRuleDOList);
            productBaseDO.setProductWeightModelDO(productWeightModelDO);

            List<ProductPartDO> productPartDOList=new ArrayList<>();
            BeanUtils.copyListProperties(param.getProductPartUpdateRequestList(),productPartDOList,ProductPartDO.class);
            productBaseDO.setProductPartDOList(productPartDOList);

            productManager.updateProduct(productBaseDO);

            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }


    @SystemLog(module =SystemLog.Module.PRODUCT,template="productDisable")
    @Override
    public ApiResult<Boolean> disableState(ProductUpdateStateRequest param) {
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            param.requestCheck();
            ProductInfoDO productInfoDO = new  ProductInfoDO();
            BeanUtils.copyProperties(param,productInfoDO);
            productInfoDO.setGmtModifiedPin(param.getPin());
            productDao.disableState(productInfoDO);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
    @SystemLog(module =SystemLog.Module.PRODUCT,template="productEnable")
    @Override
    public ApiResult<Boolean> enableState(ProductUpdateStateRequest param) {
        ApiResult<Boolean> result = new ApiResult<>();
        try {
            param.requestCheck();
            ProductInfoDO productInfoDO = new  ProductInfoDO();
            BeanUtils.copyProperties(param,productInfoDO);
            productInfoDO.setGmtModifiedPin(param.getPin());
            productDao.enableState(productInfoDO);
            result.setCode(CommonEnum.REQUEST_SUCCESS.getCode());
            result.setMessage(CommonEnum.REQUEST_SUCCESS.getMessage());
            result.setData(true);
        } catch (Exception e) {
            log.error(CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
            ExceptionProcessorUtils.wrapperHandlerException(result, e);
        }
        return result;
    }
}
